/**
 * @file common_version.cpp
 * @brief Implementation of version information functions
 */

#include "common_version.h"
#include <cstdio>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <chrono>
#include <cstdint>

namespace El {
namespace Common {

// 产品类型字符串数组
static const char *product_type_str[] = {"ipc", "nvr", "dvr", "vth", "vtm", "vto", "end", "mic"};

// 单例实现
VersionManager &VersionManager::GetInstance()
{
    static VersionManager instance;
    return instance;
}

// 获取产品类型字符串
std::string VersionManager::GetProductTypeStr(ProductType type) const
{
    if (static_cast<int32_t>(type) >= static_cast<int32_t>(ProductType::MAX)) {
        return "unknown";
    }
    return product_type_str[static_cast<int32_t>(type)];
}

// 获取产品型号字符串
std::string VersionManager::GetProductModel(ProductType type, int32_t series, int32_t model) const
{
    if (static_cast<int32_t>(type) >= static_cast<int32_t>(ProductType::MAX) || series <= 0 ||
        series >= static_cast<int32_t>(ProductSeries::MAX) || model < 0 || model > 99) {
        return "unknown";
    }

    std::ostringstream oss;
    oss << product_type_str[static_cast<int32_t>(type)] << series << std::setw(2) << std::setfill('0') << model;
    return oss.str();
}

// 获取基本版本号 (Major.Minor.Patch)
std::string VersionManager::GetVersionBasic() const
{
    std::ostringstream oss;
    oss << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_PATCH;
    return oss.str();
}

// 获取带构建时间和git哈希的完整版本号
std::string VersionManager::GetVersionFull() const
{
    // 使用宏定义的SOURCE_DATE_EPOCH作为编译时间
    auto build_time_point = std::chrono::system_clock::from_time_t(SOURCE_DATE_EPOCH);
    std::time_t build_time = std::chrono::system_clock::to_time_t(build_time_point);
    std::tm *tm_build = std::localtime(&build_time);

    char time_str[16] = {0};
    std::strftime(time_str, sizeof(time_str), "%Y%m%d%H%M", tm_build);

    std::ostringstream oss;
    oss << "V" << GetVersionBasic() << "." << time_str << ".";

    // 使用GIT_HASH宏定义
#ifdef GIT_HASH
    oss << GIT_HASH;
#else
    oss << "unknown";
#endif

    return oss.str();
}

// 获取版本号的各个组成部分
void VersionManager::GetVersionComponents(int32_t &major, int32_t &minor, int32_t &patch) const
{
    major = VERSION_MAJOR;
    minor = VERSION_MINOR;
    patch = VERSION_PATCH;
}

// 产品特性信息获取函数
std::string VersionManager::GetProductFeatures(ProductType type, uint32_t series) const
{
    // 系列必须在有效范围内
    if (static_cast<int32_t>(type) >= static_cast<int32_t>(ProductType::MAX) || series == 0 ||
        series >= static_cast<uint32_t>(ProductSeries::MAX)) {
        return "Unknown features";
    }

    // 这里可以根据设计文档中的产品特性表格增加更详细的描述
    static const char *ipc_features[] = {
        "Unknown",
        "最高2MP, 25fps, 单向音频, 基础AI, TF卡存储",   /* 经济型 */
        "最高4MP, 30fps, 双向音频, 标准AI, TF卡存储",   /* 标准型 */
        "最高8MP, 60fps, 双向降噪, 专业AI, TF+NAS存储", /* 专业型 */
        "最高12MP, 60fps, 双向降噪, 企业AI, 全存储",    /* 企业型 */
        "最高16MP, 120fps, 全功能音频, 旗舰AI, 全存储"  /* 旗舰型 */
    };

    static const char *end_features[] = {
        "Unknown",
        "1080P, 5.5mm探头, 1-2m长度, 基础照明, 家用/管道检测", /* 经济型 */
        "2K, 4.5mm探头, 2-3m长度, 可更换镜头, 工业检测",       /* 标准型 */
        "4K, 3.5mm探头, 3-5m长度, 3D成像, 医疗诊断",           /* 专业型 */
        "4K HDR, 2.8mm探头, 5-10m长度, AI识别, 精密工业",      /* 企业型 */
        "8K, 2.0mm探头, >10m长度, AI诊断, 医疗手术"            /* 旗舰型 */
    };

    static const char *mic_features[] = {
        "Unknown",
        "40-400x, 1080P, 数码成像, 基础测量, 教育/家用", /* 经济型 */
        "100-1000x, 2K, 光学+数码, 相差观察, 实验室",    /* 标准型 */
        "400-2000x, 4K, 荧光成像, 荧光成像, 生物研究",   /* 专业型 */
        "1000-5000x, 8K, 电子成像, 3D重建, 材料分析",    /* 企业型 */
        ">10000x, 16K, 混合成像, AI分析, 科研机构"       /* 旗舰型 */
    };

    // 基于产品类型返回相应的特性描述
    switch (type) {
        case ProductType::IPC:
            return (series < static_cast<uint32_t>(sizeof(ipc_features) / sizeof(ipc_features[0])))
                       ? ipc_features[series]
                       : "Unknown IPC features";
        case ProductType::END:
            return (series < static_cast<uint32_t>(sizeof(end_features) / sizeof(end_features[0])))
                       ? end_features[series]
                       : "Unknown Endoscope features";
        case ProductType::MIC:
            return (series < static_cast<uint32_t>(sizeof(mic_features) / sizeof(mic_features[0])))
                       ? mic_features[series]
                       : "Unknown Microscope features";
        default:
            return "Features not defined for this product type";
    }
}

} // namespace Common
} // namespace El